package com.xudu.xianrendongculturaltravelbackend.controller;


import cn.hutool.core.lang.Pair;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import com.xudu.xianrendongculturaltravelbackend.algorithm.TagMatchAlgorithmUtil;
import com.xudu.xianrendongculturaltravelbackend.common.BaseResponse;
import com.xudu.xianrendongculturaltravelbackend.common.DeleteRequest;
import com.xudu.xianrendongculturaltravelbackend.common.ResultUtils;
import com.xudu.xianrendongculturaltravelbackend.exception.ErrorCode;
import com.xudu.xianrendongculturaltravelbackend.exception.ThrowUtils;
import com.xudu.xianrendongculturaltravelbackend.model.dto.route.RouteAddRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.route.RouteQueryRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.route.RouteUpdateRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.scenic.ScenicAddRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.scenic.ScenicQueryRequest;
import com.xudu.xianrendongculturaltravelbackend.model.dto.scenic.ScenicUpdateRequest;
import com.xudu.xianrendongculturaltravelbackend.model.entity.Route;
import com.xudu.xianrendongculturaltravelbackend.model.entity.Scenic;
import com.xudu.xianrendongculturaltravelbackend.model.entity.User;
import com.xudu.xianrendongculturaltravelbackend.model.vo.RouteVO;
import com.xudu.xianrendongculturaltravelbackend.model.vo.ScenicVO;
import com.xudu.xianrendongculturaltravelbackend.service.RouteService;
import com.xudu.xianrendongculturaltravelbackend.service.UserService;
import jakarta.servlet.http.HttpServletRequest;

import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;


@RestController
@RequestMapping("/route")
public class RouteController {

    @Resource
    private RouteService routeService;

    @Resource
    private UserService userService;


    /**
     * 添加标签
     * 前端以from-data提交，所以使用MultipartFile接收
     */
    @PostMapping(value = "/add")
    BaseResponse<Long> addRoute(RouteAddRequest routeAddRequest, HttpServletRequest request) {
        String routeName = routeAddRequest.getRouteName();
        ThrowUtils.throwIf(routeName == null, ErrorCode.PARAMS_ERROR);

        return ResultUtils.success(routeService.addRoute(routeAddRequest, request));
    }

    @GetMapping("/list/vo")
    BaseResponse<List<RouteVO>> getListRouteVO(RouteQueryRequest routeQueryRequest) {
        List<RouteVO> routeVOList = routeService.getRouteVOList(routeQueryRequest);
        return ResultUtils.success(routeVOList);
    }

    @GetMapping("/page/list/vo")
    BaseResponse<Page<RouteVO>> getPageListRouteVO(RouteQueryRequest routeQueryRequest) {
        Page<RouteVO> pageListRouteVo = routeService.getPageListRouteVo(routeQueryRequest);
        return ResultUtils.success(pageListRouteVo);
    }

    @PostMapping("/update")
    BaseResponse<Boolean> updateRoute(RouteUpdateRequest routeUpdateRequest) {
        Long id = routeUpdateRequest.getId();
        ThrowUtils.throwIf(id <= 0, ErrorCode.PARAMS_ERROR);

        return ResultUtils.success(routeService.updateRoute(routeUpdateRequest));

    }


    @PostMapping("delete")
    BaseResponse<Boolean> deleteRoute(@RequestBody DeleteRequest deleteRequest) {
        Long id = deleteRequest.getId();
        ThrowUtils.throwIf(id == null || id <= 0, ErrorCode.PARAMS_ERROR);
        boolean delete = routeService.removeById(id);
        ThrowUtils.throwIf(!delete, ErrorCode.OPERATION_ERROR);
        return ResultUtils.success(delete);
    }

    @GetMapping("/recommend/list/vo")
    BaseResponse<List<RouteVO>> recommendRoute(HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        String userTags = loginUser.getTags();
        Gson gson = new Gson();
        List<String> userTagList = gson.fromJson(userTags, new TypeToken<List<String>>() {
        }.getType());


        QueryWrapper<Route> queryWrapper = new QueryWrapper<>();
        // queryWrapper.select("id", "routeTags");
        queryWrapper.isNotNull("routeTags");
        List<Route> routeList = routeService.list(queryWrapper);


        // 依次计算用户标签和路线标签之间的相似度
        List<Pair<Route, Long>> list = new ArrayList<>();
        for (Route route : routeList) {
            String routeTags = route.getRouteTags();
            if (StringUtils.isBlank(routeTags)) {
                continue;
            }
            List<String> routeTagsList = gson.fromJson(routeTags, new TypeToken<List<String>>() {
            }.getType());
            long similarity = TagMatchAlgorithmUtil.minDistance(userTagList, routeTagsList);
            list.add(new Pair<>(route, similarity));
        }

        // 按相似度排序
        List<Pair<Route, Long>> topRoutePairList = list.stream()
                .sorted((a, b) -> (int) (a.getValue() - b.getValue()))
                .limit(8)
                .toList();

        // 原本的顺序列表
        // List<Route> topRouteList = topRoutePairList.stream().map(Pair::getKey).collect(Collectors.toList());
        ArrayList<Route> finalRouteList = new ArrayList<>();
        for (Pair<Route, Long> pair : topRoutePairList) {
            finalRouteList.add(pair.getKey());
        }

        List<RouteVO> routeVoList = finalRouteList.stream().map(route -> {
            return routeService.objToVo(route);
        }).toList();

        return ResultUtils.success(routeVoList);

    }


}